/* app_lwip_tcp_client_loop.c */

#include "app_inc.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
static err_t app_lwip_tcp_client_loop_connect(void *arg, struct tcp_pcb *tpcb, err_t err);
static err_t app_lwip_tcp_client_loop_poll(void *arg, struct tcp_pcb *tpcb);
static err_t app_lwip_tcp_client_loop_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);

/*******************************************************************************
 * Code
 ******************************************************************************/
/* 客户端线程初始化完成后, 连上特定的服务器端口, 并周期发送字符串. */
void app_lwip_tcp_client_loop_init(void)
{

    struct tcp_pcb * pcb = tcp_new();

    /* 设置目标服务器地址为环回地址 */
    struct ip_addr ipaddr;
    IP4_ADDR(&ipaddr, 127, 0, 0, 1);

    /* 连接服务器的6060端口, 并且注册连接函数.
     * 一旦客户端连接成功, 将由lwip自动调用app_lwip_tcp_client_loop_connect()函数. */
    tcp_connect(pcb, &ipaddr, 6060, app_lwip_tcp_client_loop_connect);
}

/* 连接成功后, lwip自动调用本函数.
 * 本函数先处理环回接口收数任务, 在执行发数操作.
 * 在第一次调用本函数时, 收到数据长度为0, 但是发送一组数; 下次收到的数就是本次发送的数.
 */
static err_t app_lwip_tcp_client_loop_connect(void *arg, struct tcp_pcb *tpcb, err_t err)
{
    tcp_recv(tpcb, app_lwip_tcp_client_loop_recv);
    tcp_poll(tpcb, app_lwip_tcp_client_loop_poll, 10); /* 10个tcp定时周期 = 5秒. */
    return ERR_OK;
}

/* tcp client 接收tcp数据包 */
static err_t app_lwip_tcp_client_loop_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
    if (p != NULL)
    {
        tcp_recved(pcb, p->tot_len);
        printf("[Client]recive data, len = %d\r\n", p->tot_len);
        pbuf_free(p);
    }
    else if (err == ERR_OK)
    {
        return tcp_close(pcb);
    }

    return ERR_OK;
}

/* tcp client 发送tcp数据包. */
static err_t app_lwip_tcp_client_loop_poll(void *arg, struct tcp_pcb *tpcb)
{
    char loopdata[32] = {0,};
    static unsigned int count = 0;
    int len = 0;

    len = sprintf(loopdata, "loop_netif, count = %u", count++);

    tcp_write(tpcb, loopdata, len, TCP_WRITE_FLAG_COPY);
    return ERR_OK;
}

/* EOF. */

